<?php

namespace app\api\controller\v48;

use app\api\controller\v2\Auth;
use app\common\cachemodel\acquired_astro\AppAcquiredAstroAnswerRecord;
use app\common\cachemodel\acquired_astro\AppAcquiredAstroTestRecord;
use app\common\cachemodel\acquired_astro\ZhunleappAstroExercise;
use app\common\cachemodel\ZlUserVip;
use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use think\response\Json;

class AcquiredAstroUser extends Auth
{
    /**
     * 我的测试
     * @return Json
     * @throws \Exception
     */
    public function myList()
    {
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        $pageData = $acquiredAstroTestRecordModel->getListPage($this->user['id']);
        $resList = [];
        foreach ($pageData['data'] as $datum)
        {
            $datum = $acquiredAstroTestRecordModel->dataInit($datum);
            if ($datum['status'] === 0)
            {
                continue;
            }
            $title = $datum['type'] === 1 ? '后天星座 - VIP体验版' : '后天星座 - 完整版测试';
            // 0=>待测试 1=>测试完成等待计算 2=>计算中 3=>计算完成 4=>计算失败
            if (in_array($datum['status'], [1, 2, 4], true))
            {   //  计算中
                $link = "acquired_astro_examination_result?id={$datum['id']}&status=1&need_auth=2";
            } else
            {   //  已完成
                $link = "acquired_astro_examination_result?id={$datum['id']}&status=2&need_auth=2";
            }
            $resList[] = [
                'title' => $title,
                'create_time' => date('Y-m-d H:i', $datum['test_suc_time']),
                'target' => 'local',
                'link' => $link,
            ];
        }
        $pageData['data'] = $resList;

        return show(config('code.success'), '请求成功', $pageData);
    }

    /**
     * 开始 测试
     * @return Json
     * @throws \Exception
     */
    public function startTest()
    {
        $type = input('type/d', 0); // 测试类型 1=>vip体验版 2=>完整版
        $status = input('status/d', 0); // 1=>继续 2=>重新开始测试
        if (!in_array($type, [1, 2], true) || !in_array($status, [1, 2], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        if (Util::commentCheck($this->user['id'], ['action' => 'startTest', 'type' => $type, 'status' => $status], 3) && (int)$this->user['id'] != 10834769)
        {//mark 17333657763 手机号的uid为10834769，可以测试并发
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }
        $answerData = null;
        $acquiredAstroAnswerRecordModel = new AppAcquiredAstroAnswerRecord();
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        if ($status === 1)
        {   // 继续测试
            $answerData = $acquiredAstroAnswerRecordModel->getUserAnswerData($this->user['id']); // 获取最近一次答题记录
            if ($type === 1 && $answerData['index'] >= 20 || ($type === 2 && $answerData['index'] >= 100))
            {   // vip体验版
                $answerData = null;
            }
        }
        if (!$answerData || ($type === 2 && $answerData['record_id'] === 0))
        {   // 重新开始测试
            $initTestQuestionData = (new ZhunleappAstroExercise())->getInitTestQuestionData($type);
            $recordId = 0;
            $index = 0;
            if ($type === 2)
            {   // 完整版 重新开始测试 判断用户是否已经购买完整版
                $delayTestData = $acquiredAstroTestRecordModel->getDelayTestData($this->user['id']);
                if (!$delayTestData)
                {
                    return show(config('code.error'), '服务异常，完整版测试需要先购买完整版哦～');
                }
                $recordId = $delayTestData['id'];
                if (isset($answerData) && $answerData)
                {
                    if (isset($answerData['answer_data']['q1_num'], $answerData['answer_data']['q1']) && $answerData['answer_data']['q1_num'] > 0)
                    {
                        $initTestQuestionData['q1'] = $answerData['answer_data']['q1'];
                        $initTestQuestionData['q1_num'] = $answerData['answer_data']['q1_num'];
                    }
                    if (isset($answerData['answer_data']['q2_num'], $answerData['answer_data']['q2']) && $answerData['answer_data']['q2_num'] > 0)
                    {
                        $initTestQuestionData['q2'] = $answerData['answer_data']['q2'];
                        $initTestQuestionData['q2_num'] = $answerData['answer_data']['q2_num'];
                    }
                    if (isset($answerData['answer_data']['q3_num'], $answerData['answer_data']['q3']) && $answerData['answer_data']['q3_num'] > 0)
                    {
                        $initTestQuestionData['q3'] = $answerData['answer_data']['q3'];
                        $initTestQuestionData['q3_num'] = $answerData['answer_data']['q3_num'];
                    }
                    if (isset($answerData['answer_data']['q4_num'], $answerData['answer_data']['q4']) && $answerData['answer_data']['q4_num'] > 0)
                    {
                        $initTestQuestionData['q4'] = $answerData['answer_data']['q4'];
                        $initTestQuestionData['q4_num'] = $answerData['answer_data']['q4_num'];
                    }
                    if (isset($answerData['answer_data']['q5_num'], $answerData['answer_data']['q5']) && $answerData['answer_data']['q5_num'] > 0)
                    {
                        $initTestQuestionData['q5'] = $answerData['answer_data']['q5'];
                        $initTestQuestionData['q5_num'] = $answerData['answer_data']['q5_num'];
                    }
                    $initTestQuestionData['answer'] = $answerData['answer_data']['answer'];
                    $index = $answerData['index'];
                }
            }
            $totalNum = $initTestQuestionData['total_num'];
            unset($initTestQuestionData['total_num']);
            // 初始化 答题记录
            $initData = [
                'uid' => $this->user['id'],
                'type' => $type,
                'answer_data' => $initTestQuestionData,
                'index' => $index,
                'num' => $totalNum,
                'record_id' => $recordId,
                'create_time' => $this->request->time(),
            ];

            $id = $acquiredAstroAnswerRecordModel->saveData($initData);
            if (!$id)
            {
                return show(config('code.error'), '服务异常，请稍后再试～');
            }
            $answerData = $initData;
            $answerData['id'] = $id;
        }
        $resData = $acquiredAstroAnswerRecordModel->getQuestionAnswerDataResult($answerData);

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 提交 测试答案
     * @return Json
     * @throws ApiException
     */
    public function testSubmit()
    {
        $option = input('option/s', '');
        $type = input('type/d', 0); // 测试类型 1=>vip体验版 2=>完整版
        if (!in_array($type, [1, 2], true) || !in_array($option, ['A', 'B'], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        if (Util::commentCheck($this->user['id'], ['action' => 'startTest', 'type' => $type, 'option' => $option], 1) && (int)$this->user['id'] != 10834769)
        {//mark 17333657763 手机号的uid为10834769，可以测试并发
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }
        $acquiredAstroAnswerRecordModel = new AppAcquiredAstroAnswerRecord();
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        $testAnswerData = $acquiredAstroAnswerRecordModel->getUserAnswerData($this->user['id']); // 获取最近一次答题记录
        // 获取当前 回答的题目ID
        $qid = $acquiredAstroAnswerRecordModel->getTestAnswerQid($testAnswerData);
        // 获取 题目详情
        $questionData = (new ZhunleappAstroExercise())->getInfoById($qid);
        if (!$questionData)
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
        $answerInfo = $testAnswerData['answer_data']['answer'];
        $answerInfo[$qid] = [$option, date('Y-m-d H:i:s')];
        $testAnswerData['answer_data']['answer'] = $answerInfo;
        $testAnswerData['index']++;
        $updateData = [
            'answer_data' => $testAnswerData['answer_data'],
            'index' => $testAnswerData['index'],
        ];
        $acquiredAstroAnswerRecordModel->updateData($this->user['id'], $testAnswerData['id'], $updateData);
        if ($testAnswerData['index'] >= $testAnswerData['num'])
        {   // 答题结束
            if ($type === 1)
            {   // vip 体验版测试
                $vipLevel = (new ZlUserVip())->getUserVipLevel($this->user['id']);
                // 判断当前是否是VIP用户
                $testData = [
                    'uid' => $this->user['id'],
                    'type' => $type,
                    'answer_data' => $testAnswerData['answer_data'],
                    'content' => '',
                    'status' => $vipLevel > 0 ? 2 : 1,  // 0=>待测试 1=>测试完成等待计算 2=>计算中 3=>计算完成 4=>计算失败   【 vip用户自动测试 】
                    'create_time' => $this->request->time(),
                    'test_suc_time' => $this->request->time(),
                    'start_time' => $vipLevel > 0 ? $this->request->time() : 0, // 测试 开始计算时间
                ];
                $recordId = $acquiredAstroTestRecordModel->saveData($testData);
                if ($recordId)
                {
                    if ($testData['status'] === 2)
                    {   // 计算中 加入队列
                        Util::queuePush('acquired_astro_test_answer', ['id' => $recordId]);
                    }
                    $resData = $acquiredAstroTestRecordModel->getTestAnswerStatusData($type, $this->user['id'], $recordId, $testAnswerData['answer_data'], $testData['status'], $vipLevel);
                    $resData['style'] = 2;
                    return show(config('code.success'), '请求成功', $resData);
                } else
                {
                    return show(config('code.error'), '服务异常，请稍后再试～');
                }
            } else
            {   // 完整版
                $testUpdateData = [
                    'answer_data' => $testAnswerData['answer_data'],
                    'status' => 2, // 0=>待测试 1=>测试完成等待计算 2=>计算中 3=>计算完成 4=>计算失败
                    'test_suc_time' => $this->request->time(),
                    'start_time' => $this->request->time(), // 测试 开始计算时间
                ];
                $res = $acquiredAstroTestRecordModel->updateData($testAnswerData['record_id'], $this->user['id'], $testUpdateData);
                if ($res)
                {   // 计算中 加入队列
                    $resData = $acquiredAstroTestRecordModel->getTestAnswerStatusData($type, $this->user['id'], $testAnswerData['record_id'], $testAnswerData['answer_data'], $testUpdateData['status']);
                    $resData['style'] = 2;
                    Util::queuePush('acquired_astro_test_answer', ['id' => $testAnswerData['record_id']]);
                    return show(config('code.success'), '请求成功', $resData);
                } else
                {
                    return show(config('code.error'), '服务异常，请稍后再试～');
                }
            }
        } else
        {   // 继续答题
            $resData = $acquiredAstroAnswerRecordModel->getQuestionAnswerDataResult($testAnswerData);
            $resData['style'] = 1;
        }
        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 获取 测试状态
     * @return Json
     * @throws \Exception
     */
    public function getTestStatus()
    {
        $id = input('id/d', 0);
        if (!$id)
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        $testAnswerData = $acquiredAstroTestRecordModel->getInfoById($id);
        if (!$testAnswerData || $testAnswerData['uid'] !== $this->user['id'])
        {
            return show(config('code.error'), '服务异常，测试信息不存在～');
        }
        $vipLevel = 0;
        //  status = 0=>待测试 1=>测试完成等待计算 2=>计算中[vip用户｜购买完整版用户 测试完 默认进入计算中] 3=>计算完成 4=>计算失败
        switch ($testAnswerData['status'])
        {
            case 1:
                // 判断当前是否是VIP用户
                $vipLevel = (new ZlUserVip())->getUserVipLevel($this->user['id']);
                if ($vipLevel > 0)
                {   // vip 已开通 进入计算中 加入计算队列
                    $acquiredAstroTestRecordModel->updateData($id, $this->user['id'], ['status' => 2, 'start_time' => $this->request->time()]);
                    $testAnswerData['status'] = 2;
                    Util::queuePush('acquired_astro_test_answer', ['id' => $id]);
                }
                break;
            case 2:
                if ($this->request->time() - $testAnswerData['start_time'] > 180)
                {   // 计算3分钟 还没有初结果 重新添加如队列
                    Util::queuePush('acquired_astro_test_answer', ['id' => $id]);
                }
                break;
            case 4:
                Util::queuePush('acquired_astro_test_answer', ['id' => $id]);
                break;
            default:
        }
        $resData = $acquiredAstroTestRecordModel->getTestAnswerStatusData($testAnswerData['type'], $this->user['id'], $id, $testAnswerData['answer_data'], $testAnswerData['status'], $vipLevel);

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 获取 测试结果
     * @return Json
     */
    public function getTestResult()
    {
        $id = input('id/d', 0);
        if (!$id)
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        $testAnswerData = $acquiredAstroTestRecordModel->getInfoById($id);
        if (!$testAnswerData || $testAnswerData['uid'] !== $this->user['id'])
        {
            return show(config('code.error'), '服务异常，测试信息不存在～');
        }
        if ($testAnswerData['status'] !== 3)
        {
            return show(config('code.error'), '数据状态异常，请稍后刷新重试～');
        }
        // 重组 测试数据
        $resData = $acquiredAstroTestRecordModel->testAnswerDataResert($testAnswerData);

        return show(config('code.success'), '请求成功', $resData);
    }

    public function traitsExplain()
    {
        $type = trim(input('type/s', ''));
        if (empty($type))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $acquiredAstroTestRecordModel = new AppAcquiredAstroTestRecord();
        $traitsExplainConfig = $acquiredAstroTestRecordModel->getTraitsExplainConfig();
        if (!isset($traitsExplainConfig[$type]))
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
        $resData = [
            'title' => '/test/acquired_astro/title/traits.png',
            'tip' => sprintf("“%s”们的心理构成中，有以下显著特征：", $traitsExplainConfig[$type]['type']),
            'text1' => $traitsExplainConfig[$type]['text1'],
            'text2' => $traitsExplainConfig[$type]['text2'],
        ];
        return show(config('code.success'), '请求成功', $resData);
    }
}